#ifndef cathlibcpp_piscmds_H
#define cathlibcpp_piscmds_H

// File:       piscmds.h
// Author:     (c) Miles Sabin, 1997
// Purpose:    private header for istream command classes.


#ifndef cathlibcpp_bool_H
#include "bool.h"
#endif

#ifndef cathlibcpp_config_H
#include "config.h"
#endif

#ifndef cathlibcpp_ios_H
#include "ios.h"
#endif


class basic_istream_char;


class IStreamCommand
{
  public:

    // constructors
    IStreamCommand() {}
    virtual ~IStreamCommand();

  protected:

    // mutators
    void execute_template(basic_istream_char& is, bool noskipws = false);

    virtual ios::iostate execute(basic_istream_char& is) = 0;

  private:

    // not implemented
    IStreamCommand(IStreamCommand const&);
    IStreamCommand& operator=(IStreamCommand const&);
};


class ExtractIntegralCommand : public IStreamCommand
{
  public:

    // constructors
    ExtractIntegralCommand(basic_istream_char& is, bool pointer = false, bool defer = false);
    ~ExtractIntegralCommand();

    // accessors
    long as_signed() const
      { return (neg_ ? -n_ : n_); }

    unsigned long as_unsigned() const
      { return (neg_ ? -n_ : n_); }

    void* as_pointer() const
      { return reinterpret_cast(void*, (neg_ ? -n_ : n_)); }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

    bool pointer_;
    unsigned long n_;
    bool neg_;
};


class ExtractBoolCommand : public ExtractIntegralCommand
{
  public:

    // constructors
    ExtractBoolCommand(basic_istream_char& is);
    ~ExtractBoolCommand();

    // accessors
    bool as_bool() const
      { return as_signed(); }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);
};


class ExtractFloatingCommand : public IStreamCommand
{
  public:

    // constructors
    ExtractFloatingCommand(basic_istream_char& is);
    ~ExtractFloatingCommand();

    // accessors
    double as_double() const
      { return d_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    double d_;
};


class ExtractCharCommand : public IStreamCommand
{
  public:

    // constructors
    ExtractCharCommand(basic_istream_char& is, bool noskipws = false);
    ~ExtractCharCommand();

    // accessors
    int as_int() const
      { return c_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    int c_;
};


class ExtractStreamBufCommand : public IStreamCommand
{
  public:

    // constructors
    ExtractStreamBufCommand(basic_istream_char& is, basic_streambuf_char* osb, int delim, bool noskipws = false);
    ~ExtractStreamBufCommand();

    // accessors
    int gcount() const
      { return gcount_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    basic_streambuf_char* osb_;
    int delim_;
    int gcount_;
};


class ExtractStringCommand : public IStreamCommand
{
  public:

    // constructors
    ExtractStringCommand
      (basic_istream_char& is, char* s, streamsize n, int delim,
       bool extract_delim, bool ws_delim, bool noskipws = false);
    ~ExtractStringCommand();

    // accessors
    int gcount() const
      { return gcount_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

    char* s_;
    streamsize n_;
    bool insert_null_;
    int delim_;
    bool extract_delim_;
    bool ws_delim_;
    int gcount_;
};


class IgnoreCommand : public IStreamCommand
{
  public:

    // constructors
    IgnoreCommand(basic_istream_char& is, streamsize n, int delim);
    ~IgnoreCommand();

    // accessors
    int gcount() const
      { return gcount_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    streamsize n_;
    int delim_;
    int gcount_;
};


class PeekCommand : public IStreamCommand
{
  public:

    // constructors
    PeekCommand(basic_istream_char& is);
    ~PeekCommand();

    // accessors
    int as_int() const
      { return c_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    int c_;
};


class ReadCommand : public IStreamCommand
{
  public:

    // constructors
    ReadCommand(basic_istream_char& is, char* s, streamsize n);
    ~ReadCommand();

    // accessors
    int gcount() const
      { return gcount_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

    char* s_;
    streamsize n_;
    int gcount_;
};


class ReadSomeCommand : public IStreamCommand
{
  public:

    // constructors
    ReadSomeCommand(basic_istream_char& is, char* s, streamsize n);
    ~ReadSomeCommand();

    // accessors
    int gcount() const
      { return gcount_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

    char* s_;
    streamsize n_;
    int gcount_;
};


class PutbackCommand : public IStreamCommand
{
  public:

    // constructors
    PutbackCommand(basic_istream_char& is, char c);
    ~PutbackCommand();

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    char c_;
};


class UngetCommand : public IStreamCommand
{
  public:

    // constructors
    UngetCommand(basic_istream_char& is);
    ~UngetCommand();

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);
};


class SyncCommand : public IStreamCommand
{
  public:

    // constructors
    SyncCommand(basic_istream_char& is);
    ~SyncCommand();

    // accessors
    int as_int() const
      { return result_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    int result_;
};


class IStreamSeekoffCommand : public IStreamCommand
{
  public:

    // constructors
    IStreamSeekoffCommand(basic_istream_char& is, int off, ios::seekdir way, ios::openmode which = ios::in|ios::out);
    ~IStreamSeekoffCommand();

    // accessors
    int as_int() const
      { return result_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    int off_;
    ios::seekdir way_;
    ios::openmode which_;
    int result_;
};


class IStreamSeekposCommand : public IStreamCommand
{
  public:

    // constructors
    IStreamSeekposCommand(basic_istream_char& is, int sp, ios::openmode which = ios::in|ios::out);
    ~IStreamSeekposCommand();

    // accessors
    int as_int() const
      { return result_; }

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

  private:

    int sp_;
    ios::openmode which_;
    int result_;
};


class DiscardWSCommand : public IStreamCommand
{
  public:

    // constructors
    DiscardWSCommand(basic_istream_char& is);
    ~DiscardWSCommand();

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);
};


class ExtractBasicStringCommand : public IStreamCommand
{
  public:

    // constructors
    ExtractBasicStringCommand(basic_istream_char& is, basic_string_char& s, streamsize n, int delim, bool getline);
    ~ExtractBasicStringCommand();

  protected:

    // mutators
    ios::iostate execute(basic_istream_char& is);

    basic_string_char& s_;
    streamsize n_;
    int delim_;
    bool getline_;
};

#endif
